﻿<template>
  <div class="file-manager">
    <!-- 工具栏 -->
    <el-row class="toolbar" :gutter="10">
      <el-col :span="12">
        <el-breadcrumb separator="/">
          <el-breadcrumb-item @click="navigateTo('')" style="cursor: pointer;">
            <el-icon><HomeFilled /></el-icon> **根目录**
          </el-breadcrumb-item>
          <el-breadcrumb-item
              v-for="(part, index) in pathParts"
              :key="index"
              @click="navigateTo(pathParts.slice(0, index + 1).join('/'))"
              style="cursor: pointer;"
          >
            {{ part }}
          </el-breadcrumb-item>
        </el-breadcrumb>
      </el-col>
      <el-col :span="12" style="text-align: right;">
        <el-button-group>
          <el-button type="primary" @click="showCreateDialog = true">
            <el-icon><FolderAdd /></el-icon> **新建文件夹**
          </el-button>
          <el-button type="success" @click="showFileDialog = true">
            <el-icon><DocumentAdd /></el-icon> **新建文件**
          </el-button>
          <el-button type="info" @click="triggerFileUpload">
            <el-icon><Upload /></el-icon> **上传文件**
          </el-button>
          <!-- 新增：上传文件夹按钮 -->
          <el-button type="warning" @click="triggerFolderUpload">
            <el-icon><FolderAdd /></el-icon> **上传文件夹**
          </el-button>
          <el-button @click="refreshList">
            <el-icon><Refresh /></el-icon> **刷新**
          </el-button>
        </el-button-group>
      </el-col>
    </el-row>

    <!-- 文件列表 -->
    <el-table
        :data="fileList"
        v-loading="loading"
        stripe
        style="width: 100%; margin-top: 20px;"
        @row-dblclick="handleRowDoubleClick"
    >
      <el-table-column prop="name" label="名称" min-width="200">
        <template #default="scope">
          <el-icon v-if="scope.row.type === 'directory'" style="margin-right: 8px; color: #409EFF;">
            <Folder />
          </el-icon>
          <el-icon v-else style="margin-right: 8px; color: #67C23A;">
            <Document />
          </el-icon>
          {{ scope.row.name }}
        </template>
      </el-table-column>
      <el-table-column prop="type" label="类型" width="100">
        <template #default="scope">
          <el-tag :type="scope.row.type === 'directory' ? 'primary' : 'success'">
            {{ scope.row.type === 'directory' ? '文件夹' : '文件' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="size" label="大小" width="120">
        <template #default="scope">
          <span v-if="scope.row.type === 'file'">{{ formatFileSize(scope.row.size) }}</span>
          <span v-else>--</span>
        </template>
      </el-table-column>
      <el-table-column prop="modified" label="修改时间" width="180" />
      <el-table-column label="操作" width="200">
        <template #default="scope">
          <el-button-group>
            <el-button
                v-if="scope.row.type === 'file'"
                size="small"
                @click="downloadFile(scope.row)"
            >
              <el-icon><Download /></el-icon> **下载**
            </el-button>
            <el-button
                v-if="scope.row.type === 'file'"
                size="small"
                type="info"
                @click="handlePreviewFile(scope.row)"
            >
              <el-icon><View /></el-icon> **预览**
            </el-button>
            <el-button
                size="small"
                type="danger"
                @click="deleteItem(scope.row)"
            >
              <el-icon><Delete /></el-icon> **删除**
            </el-button>
          </el-button-group>
        </template>
      </el-table-column>
    </el-table>

    <!-- 隐藏的文件上传输入 -->
    <input
        ref="fileInput"
        type="file"
        multiple
        style="display: none"
        @change="handleFileUpload"
    />

    <!-- 新增：隐藏的文件夹上传输入 -->
    <input
        ref="folderInput"
        type="file"
        webkitdirectory
        directory
        multiple
        style="display: none"
        @change="handleFolderUpload"
    />

    <!-- 新建文件夹对话框 -->
    <el-dialog v-model="showCreateDialog" title="新建文件夹" width="400px">
      <el-form :model="createForm" label-width="80px">
        <el-form-item label="文件夹名">
          <el-input v-model="createForm.name" placeholder="请输入文件夹名称" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCreateDialog = false">取消</el-button>
        <el-button type="primary" @click="createDirectory">确定</el-button>
      </template>
    </el-dialog>

    <!-- 新建文件对话框 -->
    <el-dialog v-model="showFileDialog" title="新建文件" width="600px">
      <el-form :model="fileForm" label-width="80px">
        <el-form-item label="文件名">
          <el-input v-model="fileForm.filename" placeholder="请输入文件名（包含扩展名）" />
        </el-form-item>
        <el-form-item label="文件内容">
          <el-input
              v-model="fileForm.content"
              type="textarea"
              :rows="10"
              placeholder="请输入文件内容"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showFileDialog = false">取消</el-button>
        <el-button type="primary" @click="createFile">确定</el-button>
      </template>
    </el-dialog>

    <!-- 文件预览对话框 -->
    <el-dialog v-model="showPreviewDialog" :title="currentPreviewFile.name" width="80%">
      <el-scrollbar height="500px">
        <pre style="white-space: pre-wrap; font-family: 'Courier New', monospace;">{{ previewContent }}</pre>
      </el-scrollbar>
      <template #footer>
        <el-button @click="showPreviewDialog = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import api from '../axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  HomeFilled,
  FolderAdd,
  DocumentAdd,
  Upload,
  Refresh,
  Folder,
  Document,
  Download,
  View,
  Delete
} from '@element-plus/icons-vue'

export default {
  name: 'FileManager',
  components: {
    HomeFilled,
    FolderAdd,
    DocumentAdd,
    Upload,
    Refresh,
    Folder,
    Document,
    Download,
    View,
    Delete
  },
  data() {
    return {
      currentPath: '',
      fileList: [],
      loading: false,
      showCreateDialog: false,
      showFileDialog: false,
      showPreviewDialog: false,
      createForm: {
        name: ''
      },
      fileForm: {
        filename: '',
        content: ''
      },
      currentPreviewFile: {},
      previewContent: ''
    }
  },
  computed: {
    pathParts() {
      return this.currentPath ? this.currentPath.split('/').filter(part => part) : []
    }
  },
  mounted() {
    this.loadFileList()
  },
  methods: {
    async loadFileList() {
      this.loading = true
      try {
        const response = await api.get('/directories', {
          params: { path: this.currentPath }
        })
        this.fileList = response.data.items
        console.log('**📂 File list loaded:**', this.fileList.length, 'items')
      } catch (error) {
        ElMessage.error('**❌ 加载文件列表失败:** ' + (error.response?.data?.detail || error.message))
      } finally {
        this.loading = false
      }
    },

    navigateTo(path) {
      this.currentPath = path
      this.loadFileList()
    },

    handleRowDoubleClick(row) {
      if (row.type === 'directory') {
        this.navigateTo(row.path)
      } else {
        this.handlePreviewFile(row)
      }
    },

    async createDirectory() {
      if (!this.createForm.name.trim()) {
        ElMessage.warning('**⚠️ 请输入文件夹名称**')
        return
      }

      try {
        await api.post('/directories', {
          path: this.currentPath,
          name: this.createForm.name
        })
        ElMessage.success('**✅ 文件夹创建成功**')
        this.showCreateDialog = false
        this.createForm.name = ''
        this.loadFileList()
      } catch (error) {
        ElMessage.error('**❌ 创建文件夹失败:** ' + (error.response?.data?.detail || error.message))
      }
    },

    async createFile() {
      if (!this.fileForm.filename.trim()) {
        ElMessage.warning('**⚠️ 请输入文件名**')
        return
      }

      try {
        await api.post('/files', {
          path: this.currentPath,
          filename: this.fileForm.filename,
          content: this.fileForm.content
        })
        ElMessage.success('**✅ 文件创建成功**')
        this.showFileDialog = false
        this.fileForm.filename = ''
        this.fileForm.content = ''
        this.loadFileList()
      } catch (error) {
        ElMessage.error('**❌ 创建文件失败:** ' + (error.response?.data?.detail || error.message))
      }
    },

    triggerFileUpload() {
      this.$refs.fileInput.click()
    },

    async handleFileUpload(event) {
      const files = Array.from(event.target.files)
      if (files.length === 0) return

      this.loading = true
      try {
        // 使用 Promise.all 来并发上传文件
        const uploadPromises = files.map(file => {
          const formData = new FormData()
          formData.append('file', file)
          formData.append('path', this.currentPath)
          return api.post('/upload', formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
          })
        });

        await Promise.all(uploadPromises);

        ElMessage.success(`**✅ 成功上传 ${files.length} 个文件**`)
        this.loadFileList()
      } catch (error) {
        ElMessage.error('**❌ 上传文件失败:** ' + (error.response?.data?.detail || error.message))
      } finally {
        this.loading = false
        event.target.value = ''
      }
    },

    downloadFile(file) {
      // **确保使用正确的API基础URL**
      const url = `${api.defaults.baseURL}/download/${file.path}`
      const link = document.createElement('a')
      link.href = url
      link.download = file.name
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      ElMessage.info('**📥 开始下载文件...**')
    },

    async handlePreviewFile(file) {
      this.loading = true;
      try {
        const response = await api.get(`/file-content/${file.path}`)
        this.currentPreviewFile = file
        this.previewContent = response.data.content
        this.showPreviewDialog = true
      } catch (error) {
        if (error.response?.status === 400) {
          ElMessage.warning('**⚠️ 无法预览二进制文件**')
        } else {
          ElMessage.error('**❌ 预览文件失败:** ' + (error.response?.data?.detail || error.message))
        }
      } finally {
        this.loading = false;
      }
    },

    async deleteItem(item) {
      try {
        await ElMessageBox.confirm(
            `确定要删除 "${item.name}" 吗？此操作不可撤销。`,
            '**⚠️ 删除确认**',
            {
              confirmButtonText: '确定删除',
              cancelButtonText: '取消',
              type: 'warning',
            }
        )

        await api.delete('/delete', {
          data: { path: item.path }
        })

        ElMessage.success(`**✅ ${item.type === 'directory' ? '文件夹' : '文件'}删除成功**`)
        this.loadFileList()
      } catch (error) {
        if (error !== 'cancel') {
          ElMessage.error('**❌ 删除失败:** ' + (error.response?.data?.detail || error.message))
        }
      }
    },

    refreshList() {
      this.loadFileList()
      ElMessage.success('**🔄 列表已刷新**')
    },

    formatFileSize(bytes) {
      if (bytes === 0) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    },

    triggerFolderUpload() {
      this.$refs.folderInput.click()
    },

    // *** MODIFIED FOR FOLDER UPLOAD ***
    async handleFolderUpload(event) {
      const files = Array.from(event.target.files);
      if (files.length === 0) return;

      this.loading = true;
      try {
        // **1. 创建一个FormData实例来容纳所有文件和路径**
        const formData = new FormData();

        // **2. 遍历所有文件，将文件和它们的相对路径添加到FormData中**
        //    后端期望两个列表：`files`和`paths`
        for (const file of files) {
          formData.append('files', file);
          formData.append('paths', file.webkitRelativePath);
        }

        // **3. 添加目标基础路径**
        //    这是文件夹将被上传到的当前目录
        formData.append('basePath', this.currentPath);

        // **4. 发送单个请求到专用的文件夹上传端点**
        const response = await api.post('/upload-folder', formData, {
          headers: {
            // FormData会自动设置正确的Content-Type，但明确指定也无妨
            'Content-Type': 'multipart/form-data'
          }
        });

        // **使用后端返回的更详细的消息**
        ElMessage.success(`**✅ ${response.data.message || '文件夹上传成功'}**`);
        this.loadFileList();

      } catch (error) {
        ElMessage.error('**❌ 文件夹上传失败:** ' + (error.response?.data?.detail || error.message));
      } finally {
        this.loading = false;
        // **清空输入值，以便可以再次上传同一个文件夹**
        event.target.value = '';
      }
    }
  }
}
</script>

<style scoped>
.file-manager {
  padding: 20px;
}

.toolbar {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 6px;
}

.el-breadcrumb {
  font-size: 16px;
}

.el-table {
  border-radius: 6px;
  overflow: hidden;
}

pre {
  background-color: #f5f7fa;
  padding: 15px;
  border-radius: 6px;
  margin: 0;
}
</style>
